package com.magicmovie.service.impl;

import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.magicmovie.entity.Customer;
import com.magicmovie.entity.Order;
import com.magicmovie.mapper.CustomerMapper;
import com.magicmovie.mapper.OrderMapper;
import com.magicmovie.service.OrderService;
import com.magicmovie.utils.DateUtils;
import com.magicmovie.utils.QueryFilters;
import com.magicmovie.utils.SnowflakeIdWorker;
import com.magicmovie.utils.data.PageModel;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.RequestBody;

import java.util.*;

@Service
public class OrderServiceImpl implements OrderService {
    @Autowired
    private OrderMapper orderMapper;
    @Autowired
    private SnowflakeIdWorker snowflakeIdWorker;
    @Autowired
    private CustomerMapper customerMapper;

    private static Map<String, Object> fildMap = new HashMap<String, Object>() {
        {
            put("id", "t.id");
            put("code", "t.code");
            put("createTime", "t.create_time");
            put("payCode", "t.pay_code");
            put("siteName", "t.site_name");
            put("type", "t.type");
            put("price", "t.price");
            put("status", "t.status");
            put("movieName", "t1.movie_name");
            put("username", "t2.username");
            put("caption", "d.caption");
        }
    };
    @Override
    public Order findByUidAndMovieId(Integer uid, Integer movieId) {
        return orderMapper.findByUidAndMovieId(uid, movieId);
    }

    @Override
    public List<Map<String, Object>> findByCustomer(Integer customerId) {
        List<Map<String, Object>> res = orderMapper.findByCustomer(customerId);
        return res;
    }

    @Override
    @Transactional(readOnly = false)
    public String crateOrder(Float price, String payType, String site, Integer customerId, Integer movieId) {
        Order order = new Order();
        String orderNum = createOrderNum();
        order.setId(String.valueOf(snowflakeIdWorker.nextId()));
        order.setPrice(price);
        order.setCustomerId(customerId);
        order.setCode(orderNum);
        order.setPayType(payType);
        order.setSiteName(site);
        order.setStatus("00");
        if (movieId != null)
            order.setMovieId(movieId);
        orderMapper.insert(order);
        return orderNum;
    }

    @Override
    public Order findByOrderNum(String orderNum) {
        return orderMapper.findByOrderNum(orderNum);
    }

    @Override
    @Transactional(readOnly = false)
    public void update(@RequestBody Order order) {
        orderMapper.updateByPrimaryKeySelective(order);
    }

    @Override
    @Transactional(readOnly = false)
    public void payByBalance(@RequestBody Order order) {
        order.setStatus("01");
        orderMapper.updateByPrimaryKeySelective(order);

        Customer customer = customerMapper.selectByPrimaryKey(order.getCustomerId());
        customer.setBalance(customer.getBalance() - order.getPrice());
        customerMapper.updateByPrimaryKeySelective(customer);
    }

    @Override
    @Transactional(readOnly = false)
    public void updateOrderStatus(@RequestBody Order order) {
        order.setStatus("01");
        orderMapper.updateByPrimaryKeySelective(order);

        if (order.getMovieId() == null) {
            Customer customer = customerMapper.selectByPrimaryKey(order.getCustomerId());
            customer.setBalance(customer.getBalance() + order.getPrice());
            customerMapper.updateByPrimaryKeySelective(customer);
        }
    }

    @Override
    public PageModel getByFilter(@RequestBody QueryFilters filters) {
        Page pages = PageHelper.startPage(filters.getPageNo(), filters.getPageSize(), true, false);

        filters.format(fildMap);
        Page<Map<String, Object>> page = orderMapper.getByFilter(filters);

        PageModel model = new PageModel<>();
        model.setTotalRecord(Math.toIntExact(page.getTotal()));
        model.setPageNo(page.getPageNum());
        model.setPageSize(page.getPageSize());
        model.setResults(page.getResult());
        model.setTotalPage(page.getPages());
        return model;
    }

    @Override
    public List<Map<String, Object>> getSitesList(@RequestBody QueryFilters filters) {
        PageHelper.startPage(filters.getPageNo(), filters.getPageSize(), true, false);
        String endTime = DateUtils.formatDate(new Date());
        Calendar calendar = Calendar.getInstance();
        calendar.add(Calendar.DAY_OF_MONTH, -7);
        String startTime = DateUtils.formatDate(calendar.getTime());

        Page<Map<String, Object>> page = orderMapper.getSitesList(startTime, endTime);
        return page.getResult();
    }

    @Override
    public List<Map<String, Object>> siteDetails(@RequestBody QueryFilters filters) {
        PageHelper.startPage(filters.getPageNo(), filters.getPageSize(), true, false);
        Page<Map<String, Object>> page = orderMapper.siteDetails(filters);
        return page.getResult();
    }

    @Override
    public List<Map<String, Object>> bestSellingList() {
        return orderMapper.bestSellingList();
    }

    @Override
    public List<Map<String, Object>> mostPaidUser() {
        return orderMapper.mostPaidUser();
    }

    /**
     * 根据类型统计
     * 1： 统计总付费用户 2:总订单数 3：订单总价 4：总域名数
     *
     * @param type
     * @return
     */
    @Override
    public Integer statisticsByType(Integer type) {
        switch (type) {
            case 1:
                return orderMapper.queryPayedCustomer();
            case 2:
                return orderMapper.queryOrderCount();
            case 3:
                return orderMapper.queryOrderAmount();
            case 4:
                return orderMapper.querySiteCount();
            default:
                return 0;
        }
    }

    @Override
    public Double getMoneyByFilter(@RequestBody QueryFilters filters) {
        return orderMapper.getMoneyByFilter(filters);
    }


    private String createOrderNum() {
        int machineId = 1;//最大支持1-9个集群机器部署
        int hashCodeV = UUID.randomUUID().toString().hashCode();
        if (hashCodeV < 0) {//有可能是负数
            hashCodeV = -hashCodeV;
        }
        //         0 代表前面补充0
        //         4 代表长度为4
        //         d 代表参数为正数型
        return machineId + String.format("%015d", hashCodeV);
    }
}
